學組語的目的,不見得是為了改善效能,而是:
- 判斷 optimizing compiler 產生的機械碼是否正確
- gcc 和 clang/llvm 引入大量的最佳化技術,已很難光看原始程式碼,去推知最終生成的機械碼
[ARM 指令 Jserv 筆記中有提起]
在開始深入探討前,先來看看ARM 的 Memory system
label
opcode operand1, operand2, ...; Comments
MOV R0, #0x12 ; Set R0 = 0x12 (hexadecimal)
MOV R1, #'A' ; Set R1 = ASCII character A
NVIC_IRQ_SETEN0 EQU 0xE000E100
NVIC_IRQ0_ENABLE EQU 0x1
LDR R0,=NVIC_IRQ_SETEN0; ; LDR here is a pseudo-instruction that
; convert to a PC relative load by
; assembler.
MOV R1,#NVIC_IRQ0_ENABLE ; Move immediate data to register
STR R1,[R0] ; Enable IRQ 0 by writing R1 to address
; in R0
可分成三大項:
- Data processing
- move
- arithmetic
- logical
- comparison
- multiply
- Data movement (memory access)
- Flow control
資料處理指令包含對資料做 移動、算數、邏輯、比較、乘法 的指令
Arithmetic operations
ADD r0, r1, r2 ; r0 := r1 + r2
ADC r0, r1, r2 ; r0 := r1 + r2 + C
SUB r0, r1, r2 ; r0 := r1 - r2
SBC r0, r1, r2 ; r0 := r1 - r2 + C - 1
RSB r0, r1, r2 ; r0 := r2 - r1
RSC r0, r1, r2 ; r0 := r2 - r1 + C - 1
Bit-wise logical operations
AND r0, r1, r2 ; r0 := r1 and r2
ORR r0, r1, r2 ; r0 := r1 or r2
EOR r0, r1, r2 ; r0 := r1 xor r2
BIC r0, r1, r2 ; r0 := r1 and not r2
Register movement operations:
在ARM 的指令中加了許多條件執行的後綴
Comparison operations:
data processing 指令可以更新 PSR
CMP R0, R1 ; Calculate R0 – R1 and update flag
CMP R0, #0x12 ; Calculate R0 – 0x12 and update flag
CMN R0, R1 ; Calculate R0 – (-R1) and update flag
CMN R0, #0x12 ; Calculate R0 – (-0x12) and update flag
TST R0, R1 ; Calculate R0 AND R1 and update flag
TST R0, #0x12 ; Calculate R0 AND 0x12 and update flag
Immediate operands:
ADD r3, r3, #1 ; r3 := r3 + 1
AND r8, r7, #&ff ; r8 := r7[7:0]
load_32bit:
ldr r0, [pc #0] ;請注意: pc 位於目前位址向前 8 bytes 的地方
bx lr
.word 0xDEADBEEF
movw r0, #0xbeef ; r0 = 0x0000beef
movt r0, #0xdead ; r0 = deadbeef
.equ label, 0xDEADBEEF
movw r0, #:lower16:label
movt r0, #:upper16:label
Shifted register operands:
先介紹到這 明天繼續介紹剩下的指令集
Definitive Guide To the ARM Cortex-M3